/*
 * AbstractController.java
 *
 * Created on January 22, 2007, 8:41 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package co.edu.usbcali.raju.core;

import java.io.Serializable;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.List;

import co.edu.usbcali.raju.games.MoveEvent;
import co.edu.usbcali.raju.games.MoveListener;
import co.edu.usbcali.raju.games.SetupListener;
import co.edu.usbcali.raju.model.Board;
import co.edu.usbcali.raju.model.Move;

public abstract class AbstractController  extends UnicastRemoteObject  implements SetupListener,Serializable{
    
    //  Vectors that hold a list of the registered models and views for this controller.
	//TODO Arreglar lo de los listeners
    
    private List<AbstractViewPanel> registeredViews;
    private Board model;
    
    
    /** Creates a new instance of Controller */
    public AbstractController()  throws RemoteException{
        registeredViews = new ArrayList<AbstractViewPanel>();
    }

    
    /**
     * Binds a model to this controller. Once added, the controller will listen for all 
     * model property changes and propogate them on to registered views. In addition,
     * it is also responsible for resetting the model properties when a view changes
     * state.
     * @param model The model to be added
     */
    public void setModel(Board model) {
        this.model=model;
//        model.addSetupListener(this);
    }

    /**
     * Unbinds a model from this controller.
     * @param model The model to be removed
     */
    public void removeModel() {
      //  model.removeSetupListener(this);
        model=null;
    }
    
    public Board getModel(){
    	return model;
    }
    
    
    /**
     * Binds a view to this controller. The controller will propogate all model property
     * changes to each view for consideration.
     * @param view The view to be added
     */
    public void addView(AbstractViewPanel view) {
        registeredViews.add(view);
    }

    /**
     * Unbinds a view from this controller.
     * @param view The view to be removed
     */
    public void removeView(AbstractViewPanel view) {
        registeredViews.remove(view);
    }
    
	public void notifyMoveListeners(Move move){
		MoveEvent moveEvent=new MoveEvent(model,move);
		
		for (MoveListener listener : registeredViews) {
			listener.movePerformed(moveEvent);
		}
	}
	
	public void notifySetupListeners(){
		for (SetupListener listener : registeredViews) {
			listener.setupPerformed(model);
		}
	}

	public abstract Board doMove(Move move);
	
	/**
	 * No se hacen explicitos. Estos metodos ya los manejan las vistas registradas
	public abstract void addMoveListener(MoveListener moveListener);
	public abstract boolean removeMoveListener(MoveListener moveListener);
	public abstract void addSetupListener(SetupListener setupListener);
	public abstract boolean removeSetupListener(SetupListener setupListener);
	**/
        
}
